﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Configuration;
using System.Web;

using System.Xml.Serialization;
using System.Xml;

namespace UVM_Utileria
{
    public class Utilerias
    {
        public static string Encriptar(string msmDecript)
        {
            string passBase = GetValueAppConfig("passBase");
            string saltValue = GetValueAppConfig("saltValue");
            string hashAlgorithm = GetValueAppConfig("hashAlgorithm");
            string initVector = GetValueAppConfig("initVector");
            return pEncriptar(msmDecript, passBase, saltValue, hashAlgorithm, 1, initVector, 128);
        }

        public static string Decriptar(string msmEncript)
        {
            string passBase = GetValueAppConfig("passBase");
            string saltValue = GetValueAppConfig("saltValue");
            string hashAlgorithm = GetValueAppConfig("hashAlgorithm");
            string initVector = GetValueAppConfig("initVector");
            return pDesencriptar(msmEncript, passBase, saltValue, hashAlgorithm, 1, initVector, 128);
        }

        #region Encriptar
        private static string pEncriptar(string textoQueEncriptaremos,
        string passBase, string saltValue, string hashAlgorithm,
        int passwordIterations, string initVector, int keySize)
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(textoQueEncriptaremos);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passBase,
              saltValueBytes, hashAlgorithm, passwordIterations);
            byte[] keyBytes = password.GetBytes(keySize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor,
             CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            byte[] cipherTextBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            string cipherText = Convert.ToBase64String(cipherTextBytes);
            return cipherText;
        }
        #endregion

        #region Decriptar
        private static string pDesencriptar(string textoEncriptado, string passBase,
        string saltValue, string hashAlgorithm, int passwordIterations,
        string initVector, int keySize)
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
            byte[] cipherTextBytes = Convert.FromBase64String(textoEncriptado);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passBase,
              saltValueBytes, hashAlgorithm, passwordIterations);
            byte[] keyBytes = password.GetBytes(keySize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes,
              initVectorBytes);
            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor,
              CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0,
              plainTextBytes.Length);
            memoryStream.Close();
            cryptoStream.Close();
            string plainText = Encoding.UTF8.GetString(plainTextBytes, 0,
              decryptedByteCount);
            return plainText;
        }
        #endregion
        public static string GetValueAppConfig(string key)
        {
            string value = string.Empty;

            if (ConfigurationManager.AppSettings[key] != null)
                value = ConfigurationManager.AppSettings[key];
            else
                throw new Exception(string.Format("{0} Es Requerido", key));

            return value;


        }


        public static string Serialize(object o)
        {
            var xs = new XmlSerializer(o.GetType());
            
            var xml = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
            settings.Indent = false;
            settings.OmitXmlDeclaration = false;
            settings.Encoding = new UTF8Encoding(true);

            XmlWriter xmlWriter = XmlWriter.Create(xml, settings);
            
            xs.Serialize(xmlWriter, o);

            return xml.ToString();
            
        }

        public static string SerializeObject(object value)
        {
            var serializer = new XmlSerializer(value.GetType());
            var settings = new XmlWriterSettings
            {
                Encoding = new UTF8Encoding(true),
                Indent = false,
                OmitXmlDeclaration = false,
                NewLineHandling = NewLineHandling.None
            };

            using (var stringWriter = new StringWriter())
            {
                using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
                {
                    serializer.Serialize(xmlWriter, value);
                }

                return stringWriter.ToString();
            }
        }

        public static string ConnectionString {
            get
            {
                string p = string.Empty;
                return ConfigurationManager.AppSettings["conect"].ToString(); //ConfigurationManager.ConnectionStrings["uvm_pretira_connection"].ToString();
            }
        }
    }
}
